home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / src / blockaddr / qu2ba_send.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-03-28  |  12.6 KB  |  497 lines

  1. /*
  2.  *     MULTI-CHANNEL MEMO DISTRIBUTION FACILITY  (MMDF)
  3.  *
  4.  *     Copyright (C) 1979,1980,1981  University of Delaware
  5.  *
  6.  *     Department of Electrical Engineering
  7.  *     University of Delaware
  8.  *     Newark, Delaware  19711
  9.  *
  10.  *     Phone:  (302) 738-1163
  11.  *
  12.  *     This program module was developed as part of the University
  13.  *     of Delaware's Multi-Channel Memo Distribution Facility (MMDF).
  14.  *
  15.  *     Acquisition, use, and distribution of this module and its listings
  16.  *     are subject restricted to the terms of a license agreement.
  17.  *     Documents describing systems using this module must cite its source.
  18.  *
  19.  *     The above statements must be retained with all copies of this
  20.  *     program and may not be removed without the consent of the
  21.  *     University of Delaware.
  22.  *
  23.  *
  24.  *     version  -1    David H. Crocker    March   1979
  25.  *     version   0    David H. Crocker    April   1980
  26.  *     version  v7    David H. Crocker    May     1981
  27.  *     version   1    David H. Crocker    October 1981
  28.  *
  29.  */
  30. /*                SEND FROM DELIVER TO SUBMIT
  31.  *
  32.  *  Feb 83  Doug Kingston       Initial version of list processor
  33.  *  Apr 86  Craig Partridge     Minor efficiency tweaking
  34.  *  Dec 87  Dan Long            Converted to address blocking function
  35.  */
  36.  
  37. #include "util.h"
  38. #include "mmdf.h"
  39. #include "phs.h"
  40. #include "ch.h"
  41. #include "ap.h"
  42. #include <pwd.h>
  43.  
  44. extern struct ll_struct   *logptr;
  45. extern Chan *chanptr;
  46. extern long qu_msglen;
  47. extern char *supportaddr;
  48.  
  49. extern char *index();
  50. extern char *rindex();
  51. extern char *strdup();
  52. extern char *multcat();
  53. extern char *blt();
  54.  
  55. extern int ml_state;              /* to fake ml_send(3) out */
  56.  
  57. LOCVAR int  nadrs, ndone, notify;
  58. LOCVAR char sender[ADDRSIZE];
  59. LOCVAR char adr[ADDRSIZE];
  60. LOCVAR int  started = FALSE;
  61. LOCVAR int  rejecting = FALSE;
  62. LOCVAR char *notifylist[128];
  63.  
  64. LOCVAR struct rp_construct
  65.     rp_bdrem =
  66. {
  67.     RP_BHST, 'B', 'a', 'd', ' ', 'r', 'e', 's', 'p', 'o', 'n', 's', 'e',
  68.     ' ', 'f', 'r', 'o', 'm', ' ', 's', 'u', 'b', 'm', 'i', 't', '\0'
  69. },
  70.     rp_adr =
  71. {
  72.     RP_AOK, 'a', 'd', 'd', 'r', 'e', 's', 's', ' ', 'o', 'k', '\0'
  73. },
  74.     rp_gdtxt =
  75. {
  76.     RP_MOK, 't', 'e', 'x', 't', ' ', 's', 'e', 'n', 't', ' ', 'o', 'k', '\0'
  77. },
  78.     rp_noop =
  79. {
  80.     RP_NOOP, 's', 'u', 'b', '-', 'l', 'i', 's', 't', ' ', 'n', 'o', 't', ' ',
  81.     's', 'p', 'e', 'c', 'i', 'a', 'l', '\0'
  82. },
  83.     rp_vhost =
  84. {
  85.     RP_USER, 'H', 'o', 's', 't', 'n', 'a', 'm', 'e', ' ', 'n', 'o', ' ', 'l',
  86.     'o', 'n', 'g', 'e', 'r', ' ', 'v', 'a', 'l', 'i', 'd', '\0'
  87. },
  88.     rp_vuser =
  89. {
  90.     RP_USER, 'U', 's', 'e', 'r', 'n', 'a', 'm', 'e', ' ', 'n', 'o', ' ', 'l',
  91.     'o', 'n', 'g', 'e', 'r', ' ', 'v', 'a', 'l', 'i', 'd', '\0'
  92. };
  93.  
  94. /* */
  95.  
  96. qu2ba_send ()             /* overall mngmt for batch of msgs    */
  97. {
  98.     short       result;
  99.     char        info[LINESIZE];
  100.  
  101. #ifdef DEBUG
  102.     ll_log (logptr, LLOGBTR, "qu2ba_send ()");
  103. #endif
  104.  
  105.     if (rp_isbad (result = qu_pkinit ()))
  106.     return (result);
  107.  
  108.     if (isstr(chanptr->ch_confstr) && lowtoup(*chanptr->ch_confstr) == 'R')
  109.     rejecting=TRUE;
  110.  
  111.     /*
  112.      *  While there are messages to process ...
  113.      */
  114.     for(;;){                /* get initial info for new message   */
  115.     result = qu_rinit (info, sender, chanptr -> ch_apout);
  116.  
  117.     switch(rp_gval(result)) {
  118.  
  119.         case RP_NS:
  120.         case RP_FIO:
  121.         qu_rend();
  122.         continue;
  123.  
  124.         case RP_OK:
  125.         break;
  126.  
  127.         default:
  128.         goto done;
  129.     }
  130.  
  131.     /* make sure submit is running */
  132.  
  133.     if ((!started) && (rp_isbad(mm_init()) || rp_isbad(mm_sbinit()))) {
  134.             /* quit... */
  135.             ll_log(logptr, LLOGTMP, "couldn't start submit");
  136.             goto done;
  137.         }
  138.     started = TRUE;
  139.     notify = 0;
  140.  
  141.     switch (rp_gbval (result = qu2ba_each())) {
  142.  
  143.         case RP_BOK:
  144.         case RP_BPOK:
  145.         break;
  146.  
  147.         case RP_BTNO:    /*  submit was difficult */
  148.         started = FALSE;
  149.         break;
  150.  
  151.         case RP_BNO:    /* deliver was difficult */
  152.         default:
  153.         goto done;
  154.     }
  155.  
  156.     if (notify)
  157.         sendnotification();
  158.  
  159.     qu_rend();
  160.     }
  161.  
  162. done:
  163.  
  164.     qu_rend();
  165.  
  166.     if (rp_gval (result) != RP_DONE) {
  167.     ll_log (logptr, LLOGFAT, "not DONE (%s)", rp_valstr (result));
  168.     return (RP_RPLY);         /* catch protocol errors              */
  169.     }
  170.  
  171.     if (started)
  172.     mm_end(OK);
  173.  
  174.     qu_pkend ();                  /* done getting messages              */
  175.     return (result);
  176. }
  177. /* */
  178.  
  179. LOCFUN
  180.     qu2ba_each ()            /* send one copy of text per message */
  181. {
  182.     struct rp_bufstruct thereply;
  183.     short   result;
  184.     int     len;
  185.     char    host[ADDRSIZE];
  186.     char    info[LINESIZE];
  187.     char    *adrp;
  188.     char    *colonp,*commap,*atp;
  189.  
  190. #ifdef DEBUG
  191.     ll_log (logptr, LLOGBTR, "qu2ba_each()");
  192. #endif
  193.  
  194.     nadrs = ndone = 0;
  195.  
  196.     /*
  197.      *  For every address in the message ...
  198.      */
  199.     while( 1 ) {
  200.     result = qu_radr (host, adr);
  201.     if (rp_isbad (result))
  202.         return (RP_BNO);      /* get address from Deliver           */
  203.  
  204.     switch (rp_gval (result))
  205.     {
  206.         case RP_HOK:          /* end of sub-list */
  207.         qu_wrply ((RP_Buf *)&rp_noop, sizeof rp_noop);
  208.         break;
  209.  
  210.         case RP_DONE:         /* end of full address list           */
  211.         if (ndone != 0) {
  212.             qu2ba_txtcpy(&thereply);
  213.                 qu_wrply(&thereply, sizeof (thereply.rp_val) +
  214.                     strlen (thereply.rp_line));
  215.             if (rp_isbad(thereply.rp_val)) {
  216.             mm_end(NOTOK);
  217.             return(RP_AGN);
  218.             }
  219.                 return (RP_OK);         /* END for this message */
  220.         } else {
  221.             qu_wrply ((RP_Buf *)&rp_bdrem, sizeof rp_bdrem);
  222.             mm_end(NOTOK);
  223.             return(RP_AGN);
  224.         }
  225.  
  226.         default:            /* actually have an address */
  227.         /* Build notification string for sender */
  228.         if ((colonp = index(adr, ':')) == (char *) 0) {
  229.  
  230.             /* username[@host] */
  231.             adrp = adr;
  232.             if ((atp = rindex (adrp, '@')) != (char *) 0)
  233.                 *atp = '\0';   /* strip hostname */         
  234.             if ((tb_k2val(chanptr->ch_table, 1, adrp, info) != OK) ||
  235.                 (strlen(info) == 0))    
  236.                 notifylist[++notify] = multcat(adrp,  
  237.                 (rejecting)?
  238.                     "\t<== This username is no longer valid\n":
  239.                     "\t <== This username is soon to expire\n",
  240.                 (char *) 0);
  241.             else
  242.                     notifylist[++notify] = multcat(adrp,
  243.                     "\t<== ", info, "\n",  (char *) 0);
  244.                 if (rejecting)
  245.                     /* Tell deliver this is a bad address */
  246.                     qu_wrply((RP_Buf *)&rp_vuser, sizeof rp_vuser);
  247.             else
  248.             /* avoid mail loops */
  249.             adrp = multcat("~", adr, (char *) 0);
  250.  
  251.         } else {
  252.  
  253.             /* @channel[,route[,route]]:username[@host] */
  254.             if ((commap=index(adr, ',')) == (char *) 0) {
  255.  
  256.             adrp=colonp+1;
  257.  
  258.             /* username[@host] */
  259.             if (((atp = rindex (adrp, '@')) == (char *) 0) ||
  260.                     (tb_k2val(chanptr->ch_table, 1, atp+1, info) != OK) ||
  261.                     (strlen(info) == 0))
  262.                     notifylist[++notify] = multcat(adrp, 
  263.                             "\t<== Use this address\n", (char *) 0);
  264.             else
  265.                 notifylist[++notify] = multcat(adrp,
  266.                     "\t<== ", info, "\n", (char *) 0);
  267.             } else {
  268.  
  269.             adrp = commap+1;
  270.  
  271.                     /* @route[,@route]:username[@host] */
  272.             if (((atp = rindex (colonp+1, '@')) == (char *) 0) ||
  273.                     (tb_k2val(chanptr->ch_table, 1, atp+1, info) != OK) ||
  274.                     (strlen(info) == 0)) {
  275.                 *colonp = '\0';
  276.                 atp = rindex(adrp,'@'); /* start of last route */
  277.                 notifylist[++notify] = multcat(colonp+1, 
  278.                     "\t<== This is probably not a good address.\n\t\t\t(Write \"Postmaster", 
  279.                                 atp, "\" for advice.)\n", (char *) 0);
  280.                 *colonp = ':';
  281.             } else
  282.                 notifylist[++notify] = multcat(colonp+1,
  283.                     "\t<== ", info, "\n", (char *) 0);
  284.             }
  285.                 if (rejecting)
  286.                     /* Tell deliver this is a bad address */
  287.                     qu_wrply((RP_Buf *)&rp_vhost, sizeof rp_vhost);
  288.         }
  289.             ll_log(logptr, LLOGFST, "%s to %s for %s",
  290.                       (rejecting)?"Rejection":"Warning", sender, adrp);
  291.  
  292.         if (!rejecting)
  293.                 if (rp_isbad(result = submitaddr(adrp)))
  294.             return(result);
  295.  
  296.     } /* end switch */
  297.     }
  298.     /* NOTREACHED */
  299. }
  300.  
  301. /* */
  302.  
  303. LOCFUN
  304.     qu2ba_txtcpy (rp)     /* copy the text of the message       */
  305. RP_Buf *rp;
  306. {
  307.     int       len;
  308.     short     result;
  309.     char      buffer[BUFSIZ];
  310.  
  311. #ifdef DEBUG
  312.     ll_log (logptr, LLOGBTR, "qu2ba_txtcpy()");
  313. #endif
  314.  
  315.     qu_rtinit (0L);
  316.  
  317.     if (rp_isbad (result = mm_waend())) {
  318.     blt ((char *)&rp_bdrem, (char *) rp, sizeof rp_bdrem);
  319.     return;
  320.     }
  321.  
  322.     printx ("sending...:");
  323.     fflush (stdout);
  324.  
  325.     len = sizeof(buffer);
  326.     while ((rp_gval (result = qu_rtxt (buffer, &len))) == RP_OK)
  327.     {
  328.     result = mm_wtxt (buffer, len);
  329.     if (rp_isbad (result))
  330.         break;
  331.     printx (".");
  332.     fflush (stdout);
  333.     if (rp_gval (result) != RP_OK) {
  334.         blt ((char *)&rp_bdrem, (char *) rp, sizeof rp_bdrem);
  335.         return;
  336.     }
  337.     len = sizeof(buffer);
  338.     }
  339.  
  340.     if (rp_isbad (result) || rp_gval (result) != RP_DONE) {
  341.     blt ((char *)&rp_bdrem, (char *) rp, sizeof rp_bdrem);
  342.     return;
  343.     }
  344.  
  345.     if (rp_isbad(mm_wtend()) || rp_isbad(mm_rrply(rp,&len))) {
  346.     rp->rp_val = RP_RPLY;
  347.     strcpy(rp->rp_line,"Unknown problem");
  348.     return;
  349.     }
  350.  
  351.     blt ((char *)&rp_gdtxt, (char *)rp, sizeof rp_gdtxt);
  352. }
  353.  
  354. /* */
  355.  
  356. LOCFUN
  357.     submitaddr(adrp)           /* pass adr to submit */
  358. char *adrp;
  359. {
  360.     struct rp_bufstruct thereply;
  361.     int len;
  362.  
  363.     /* Use the new address for resubmission */
  364.     if (nadrs++ == 0) {
  365.  
  366.         /* first address -- need to crank up submit first */
  367.             /* should allow W to be passed here */
  368.         if (rp_isbad (mm_winit (chanptr->ch_name, "tlvm", sender))
  369.           || rp_isbad (mm_rrply(&thereply, &len))) {
  370.         mm_end (NOTOK);
  371.         printx ("Error in submit startup\n");
  372.         fflush (stdout);
  373.         qu_wrply((RP_Buf *)&rp_bdrem, sizeof rp_bdrem);
  374.         return(RP_AGN);
  375.         }
  376.  
  377.         switch (rp_gbval (thereply.rp_val)) {
  378.         case RP_BNO:
  379.         case RP_BTNO:
  380.             mm_end (NOTOK);
  381.             printx ("Error in submit startup (%s)\n", thereply.rp_line);
  382.             fflush (stdout);
  383.             qu_wrply(&thereply, len);
  384.             return(RP_AGN);
  385.         }
  386.         if (rp_isbad (mm_wadr ("", adrp))
  387.              || rp_isbad (mm_rrply(&thereply, &len))) {
  388.             mm_end (NOTOK);
  389.             printx ("Error in passing first address\n");
  390.             fflush (stdout);
  391.             qu_wrply((RP_Buf *)&rp_bdrem, sizeof rp_bdrem);
  392.             return(RP_AGN);
  393.         }
  394.     }
  395.     else /* subsequest addresses */
  396.     {
  397.         if (rp_isbad (mm_wadr ("", adrp))
  398.                || rp_isbad (mm_rrply(&thereply, &len)))
  399.         {
  400.             mm_end (NOTOK);
  401.             printx ("Error in passing address\n");
  402.             fflush (stdout);
  403.             qu_wrply((RP_Buf *)&rp_bdrem, sizeof rp_bdrem);
  404.             return(RP_AGN);
  405.         }
  406.     }
  407.     
  408.     switch (rp_gval (thereply.rp_val))
  409.     {                 /* was address acceptable?            */
  410.         case RP_AOK:
  411.         case RP_DOK:
  412.         qu_wrply((RP_Buf *)&rp_adr, sizeof  rp_adr);
  413.         ndone++;
  414.         return(RP_OK);
  415.  
  416.         case RP_PARM:
  417.         case RP_USER:
  418.         case RP_NO:
  419.         case RP_NS:
  420.         break;    /* report failure and continue        */
  421.  
  422.         case RP_RPLY:
  423.         ll_log (logptr, LLOGTMP, "unusual return: (%s)%s",
  424.             rp_valstr (thereply.rp_val), thereply.rp_line);
  425.         break;    /* notify deliver */
  426.     }
  427.     /* tell deliver about all this */
  428.     qu_wrply (&thereply, len);
  429.     
  430.     return(RP_OK);
  431. }
  432.  
  433. LOCFUN
  434.     sendnotification()
  435. {
  436.     FILE *fp;
  437.  
  438.     /* send the notification */    
  439.  
  440.     if (started) /* prime ml_send */
  441.     ml_state = ML_MSG;
  442.     else
  443.         ml_state = ML_FRESH;
  444.     started = FALSE;            /* if sendnotify returns prematurely because
  445.                    an ml_send routine returned NOTOK, we know
  446.                    that ml_state will be ML_FRESH (i.e. submit
  447.                    shut down) because ml_send is very careful */
  448.  
  449.     if (ml_1adr(NO, YES, supportaddr,
  450.             (rejecting)?"Expired addresses"
  451.                      :"Soon-to-expire addresses", sender) != OK) {
  452.     ll_log(logptr, LLOGTMP, "Failed to send blockaddr warning to %s",
  453.                 sender);
  454.     return;
  455.     }
  456.  
  457.     if ((fp=fopen(chanptr->ch_confstr+1, "r")) == 0)
  458.     {
  459.         ll_log(logptr, LLOGTMP, "Blockaddr file (%s) not found.",
  460.                 chanptr->ch_confstr+1);
  461.     if (ml_txt((rejecting)?"Please resend your message with the new addresses shown below:\n":
  462.                              "Your message has been sent to the new addresses shown below:\n") != OK) {
  463.         ll_log(logptr, LLOGTMP, "Failed to send blockaddr warning to %s",
  464.                     sender);
  465.         return;
  466.     }
  467.     }
  468.     else {
  469.         if (ml_file (fp) != OK) {
  470.         ll_log(logptr, LLOGTMP, "Failed to send blockaddr warning to %s",
  471.                     sender);
  472.     fclose(fp);
  473.     return;
  474.         }
  475.         fclose(fp);
  476.     }
  477.  
  478.     ml_txt("\n");
  479.     while(notify > 0) {
  480.     if (ml_txt(notifylist[notify]) != OK) {
  481.         ll_log(logptr, LLOGTMP, "Failed to send blockaddr warning to %s", 
  482.                             sender);
  483.         return;
  484.     }
  485.     free(notifylist[notify--]);
  486.     }
  487.  
  488.     if (ml_end(OK) != OK) {
  489.     ll_log(logptr, LLOGTMP, "Failed to send blockaddr warning to %s",
  490.                             sender);
  491.     return;
  492.     }
  493.     started=TRUE;
  494.     return;    
  495.  
  496. }    
  497.